package maa.action.anonym;

import maa.action.Action;
import maa.action.ActionException;
import maa.action.ActionResult;
import maa.dao.*;
import maa.dao.h2.UserDAOimpl;
import maa.dao.DAOCommand;
import maa.database.ConnectionPool;
import maa.entity.Gender;
import maa.entity.Role;
import maa.entity.User;
import maa.util.FieldValidator;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.sql.Date;

//@MappedAction(get = "/register", post = "/register")
public class Register implements Action {
    @Override
    public ActionResult execute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        final User user = new User();
        HttpSession session = req.getSession();
        ActionResult actionResult = new ActionResult();
        String password = req.getParameter("password");
        String repeatedPassword = req.getParameter("password_check");
        String email = req.getParameter("email");
        String name = req.getParameter("name");
        String surname = req.getParameter("surname");
        String gender = req.getParameter("gender").toUpperCase();
        String birthdate = req.getParameter("birthdate");
        if (!FieldValidator.isValidEmail(email)) {
            req.setAttribute("incorrect_email", "Email should be different");
            actionResult.setResult("registration");
            keepValues(email,name,surname,req);
            return actionResult;
        }
        if (!FieldValidator.isValidPassword(password)) {
            req.setAttribute("incorrect_password", "Password should be 6 to 20 symbols and consist of at least one number, one small letter, one big letter, and one of the following symbols: @#$%-_");
            actionResult.setResult("registration");
            keepValues(email,name,surname,req);
            return actionResult;
        }
        if (!FieldValidator.isValidName(name)) {
            req.setAttribute("incorrect_name", "Name should start with a capitol letter, consist of only letters and can be 1 to 30 symbols");
            actionResult.setResult("registration");
            keepValues(email,name,surname,req);
            return actionResult;
        }
        if (!FieldValidator.isValidSurname(surname)) {
            req.setAttribute("incorrect_gender", "Surname should start with a capitol letter, consist of only letters and can be 1 to 40 symbols");
            actionResult.setResult("registration");
            keepValues(email,name,surname,req);
            return actionResult;
        }
        if (!FieldValidator.isValidGender(gender)) {
            req.setAttribute("incorrect_surname", "Gender should be either 'MALE' or 'FEMALE'");
            actionResult.setResult("registration");
            keepValues(email,name,surname,req);
            return actionResult;
        }
        if (!FieldValidator.isValidBirthdate(birthdate)) {
            req.setAttribute("incorrect_birthdate", "Birthdate should be submitted in the following format: yyyy-mm-dd");
            actionResult.setResult("registration");
            keepValues(email,name,surname,req);
            return actionResult;
        } ;
        String pass = encryptPassword(password);

        user.setPassword(pass);
        user.setEmail(email);
        user.setName(req.getParameter("name"));
        user.setSurname(req.getParameter("surname"));
        user.setBirthdate(Date.valueOf(req.getParameter("birthdate")));
        user.setGender(Gender.valueOf(req.getParameter("gender").toUpperCase()));
        user.setRole(Role.CLIENT);
        if (password.equals(repeatedPassword)) {
            ConnectionPool connectionPool = ConnectionPool.getInstance();
            DAOManager daoManager = DAOFactory.createDAOManager(connectionPool.getConnection());
            DAOCommand command = new DAOCommand() {
                @Override
                public Object execute(DAOManager daoManager) throws ActionException {
                    try {
                        UserDAOimpl userDAO = daoManager.getUserDAO();
                        return userDAO.create(user);
                    } catch (DAOException e) {
                        throw new ActionException("Exception in userDAO.create(user)");
                    }
                }
            };
            Boolean flag = (Boolean) daoManager.executeAndClose(command);

            if (flag) {
                session.setAttribute("user", user);
                actionResult.setResult("successful-registration");
                actionResult.setRedirected(true);
                return actionResult;
            } else {

            }
        } else {
            req.setAttribute("unmatching_passwords", "Password and repeated password should match. Please try again!");
            keepValues(email,name,surname,req);
            actionResult.setResult("registration");
            return actionResult;
        }

        return actionResult;
    }

    public void keepValues(String email, String name, String surname, HttpServletRequest req){
        req.setAttribute("em", email);
        req.setAttribute("na", name);
        req.setAttribute("sur", surname);
    };

    private static String encryptPassword(String password) throws NoSuchAlgorithmException, UnsupportedEncodingException
    {
        MessageDigest crypt = MessageDigest.getInstance("SHA-1");
        crypt.reset();
        crypt.update(password.getBytes("UTF-8"));
        return new BigInteger(1, crypt.digest()).toString(16);
    }
}
